
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.spi.ToolProvider;
import java.util.stream.StreamSupport;
import java.nio.file.Paths;

public class JdepsEntry {


    /**
     * 解析依赖-递归（运行时依赖）
     *
     * @param home 根目录
     * @param scanModuleName 当前扫描的模块
     * @param classes 仅支持目录（lib或者classes）或者jar
     * @return
     * @throws IOException
     */
    public static String run(String home, String scanModuleName, String classes) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        List<String> commands = new ArrayList<>();
        List<String> paths = new ArrayList<>();
        File file = Paths.get(home.strip(), classes.strip()).toFile();

        if (!file.exists()) {
            throw new FileNotFoundException(file.getAbsolutePath());
        }

        if (file.isDirectory()) {
            File[] jarFiles = file.listFiles((dir, name) -> {
                if (name.endsWith(".jar")) {
                    return true;
                }
                return false;
            });
            // 目录下有jar，结尾必须加*
            if (jarFiles != null && jarFiles.length > 0) {
                for (File jar : jarFiles) {
                    paths.add(jar.getCanonicalPath());
                }
            }
        }
        if (paths.isEmpty()) {
            paths.add(file.getCanonicalPath());
        }

        commands.add("--multi-release");
        commands.add("17");
        commands.add("-s");
        commands.add("-recursive");
        commands.add("-cp");
        commands.add(new WalkLib(home.strip(), scanModuleName.strip()).libs());
        commands.addAll(paths);

        int run = jdeps().run(new PrintWriter(byteArrayOutputStream), new PrintWriter(byteArrayOutputStream), commands.toArray(String[]::new));
        if (run == 0) {
            return byteArrayOutputStream.toString(StandardCharsets.UTF_8);
        }
        throw new IOException(byteArrayOutputStream.toString(StandardCharsets.UTF_8));
    }


    /**
     * 解析依赖-编译依赖
     *
     * @param home 根目录
     * @param scanModuleName 当前扫描的模块
     * @param classes 仅支持目录（lib或者classes）或者jar
     * @return
     * @throws IOException
     */
    public static String runClient(String home, String scanModuleName, String classes) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        List<String> commands = new ArrayList<>();
        List<String> paths = new ArrayList<>();
        File file = Paths.get(home.strip(), classes.strip()).toFile();

        if (!file.exists()) {
            throw new FileNotFoundException(file.getAbsolutePath());
        }

        if (file.isDirectory()) {
            File[] jarFiles = file.listFiles((dir, name) -> {
                if (name.endsWith(".jar")) {
                    return true;
                }
                return false;
            });
            // 目录下有jar，结尾必须加*
            if (jarFiles != null && jarFiles.length > 0) {
                for (File jar : jarFiles) {
                    paths.add(jar.getCanonicalPath());
                }
            }
        }
        if (paths.isEmpty()) {
            paths.add(file.getCanonicalPath());
        }

        commands.add("--multi-release");
        commands.add("17");
        commands.add("-s");
        commands.add("-cp");
        commands.add(new WalkLib(home.strip(), scanModuleName.strip()).libsAndClientLibs());
        commands.addAll(paths);

        int run = jdeps().run(new PrintWriter(byteArrayOutputStream), new PrintWriter(byteArrayOutputStream), commands.toArray(String[]::new));
        if (run == 0) {
            return byteArrayOutputStream.toString(StandardCharsets.UTF_8);
        }
        throw new IOException(byteArrayOutputStream.toString(StandardCharsets.UTF_8));
    }


    /**
     * 非模块化解析
     */
    private static ToolProvider jdeps() {
        Optional<ToolProvider> jdeps = ToolProvider.findFirst("jdeps");
        return jdeps.get();
    }


    /**
     * 模块化加载，gradle中禁用AbstractTask中替换的线程上下文
     */
    private static ToolProvider getJdeps() {
        ServiceLoader<ToolProvider> sl = ServiceLoader.load(ToolProvider.class, null);
        StreamSupport.stream(sl.spliterator(), false).forEach(p -> System.out.println(p.name()));

        List<ToolProvider> list = StreamSupport.stream(sl.spliterator(), false)
                .filter(p -> p.name()
                        .equals("jdeps"))
                .toList();
        return list.get(0);
    }

}
